home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 101 / CD-ROM 101.iso / compl / maya5ple / Install_MayaPLE5_English.exe / Maya / Data1.cab / doSetKeyframeArgList.mel < prev    next >
Encoding:
Text File  |  2003-07-17  |  14.3 KB  |  575 lines

  1. // Copyright (C) 1997-2002 Alias|Wavefront,
  2. // a division of Silicon Graphics Limited.
  3. //
  4. // The information in this file is provided for the exclusive use of the
  5. // licensees of Alias|Wavefront.  Such users have the right to use, modify,
  6. // and incorporate this code into other products for purposes authorized
  7. // by the Alias|Wavefront license agreement, without fee.
  8. //
  9. // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  10. // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  11. // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  12. // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  13. // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  14. // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. // PERFORMANCE OF THIS SOFTWARE.
  16. //
  17. //
  18. //  Alias|Wavefront Script File
  19. //  MODIFY THIS AT YOUR OWN RISK
  20. //
  21. //  Creation Date:  Dec 3, 1996
  22. //  Author:         hmbw + clm
  23. //
  24.  
  25. proc string[] appendArray(string $a[], string $b[]) 
  26. //
  27. //    Description:
  28. //        Appends the contents of $b onto $a
  29. //
  30. {
  31.     string $combined[] = $a;
  32.     int $nA = size($combined);
  33.  
  34.     int $nB = size($b);
  35.  
  36.     for ($ii = 0; $ii < $nB; $ii++) {
  37.         $combined[$nA++] = $b[$ii];
  38.     }
  39.  
  40.     return $combined;
  41. }
  42.  
  43. proc string[] makeUnique(string $a[]) 
  44. //
  45. //    Description:
  46. //        Returns a unique string array in alphabetcial order.
  47. //
  48. {
  49.     string $sorted[] = sort($a);
  50.  
  51.     int $index = 0;
  52.     string $newArray[];
  53.  
  54.     int $nItems = size($sorted);
  55.     if ($nItems > 0) {
  56.         $newArray[$index++] = $sorted[0];
  57.     }
  58.  
  59.     for ($ii = 1; $ii < $nItems; $ii++) {
  60.         if ($sorted[$ii] != $sorted[$ii-1]) {
  61.             $newArray[$index++] = $sorted[$ii];
  62.         }
  63.     }
  64.  
  65.     return $newArray;
  66. }
  67.  
  68. proc string[] removeIntersection(string $a[], string $b[])
  69. //
  70. //    Description:
  71. //        Returns an array with all of the elements from $a removed from
  72. //        $b.
  73. //
  74. {
  75.     string $remainder[];
  76.     int $rIndex = 0;
  77.     
  78.     int $nA = size($a);
  79.     int $nB = size($b);
  80.  
  81.     if ($nA == 0) {
  82.         return $b;
  83.     }
  84.  
  85.     for ($ii = 0; $ii < $nB; $ii++) {
  86.         int $found = false;
  87.         for ($jj = 0; $jj < $nA; $jj++) {
  88.             if ($a[$jj] == $b[$ii]) {
  89.                 $found = true;
  90.                 break;
  91.             }
  92.  
  93.             if (!$found) {
  94.                 $remainder[$rIndex++] = $b[$ii];
  95.             }
  96.         }
  97.     }
  98.  
  99.     return $remainder;
  100. }
  101.  
  102. proc string[] ikFKGetCharacterContents(string $character)
  103. //
  104. //    Description:
  105. //        Returns all of the transforms from the passed character and its 
  106. //        subcharacters.
  107. //
  108. {
  109.     string $nodes[] = `character -q -no $character`;
  110.     string $transforms[] = `ls -type transform $nodes`;
  111.  
  112.     string $characters[] = `ls -type character $nodes`;
  113.     string $char;
  114.     for ($char in $characters) {
  115.         $transforms = appendArray($transforms, ikFKGetCharacterContents($char));
  116.     }
  117.  
  118.     return $transforms;
  119. }
  120.  
  121.  
  122. proc string[] ikFKHandleObjects(string $targets[], int $mode)
  123. //
  124. //    Description:
  125. //        Sets the IK/FK keys and returns the unset target items.
  126. //
  127. {
  128.     //    If everything is a handle or a joint, just call ikFK directly
  129.     //    and return an empty array.
  130.     //
  131.     if (size(`ls -type "ikHandle" -type "joint" $targets`) == size($targets)) {
  132.         catch(ikFK($mode, $targets));
  133.         return ({});
  134.     }
  135.  
  136.     string $characters[] = `ls -type "character" $targets`;
  137.     int $nCharacters = size($characters);
  138.  
  139.     string $characterContents[];
  140.     if ($nCharacters > 0) {
  141.         string $item;
  142.         for ($item in $characters) {
  143.             string $cc[] = ikFKGetCharacterContents($item);
  144.             $characterContents = appendArray($characterContents, $cc);
  145.         }
  146.  
  147.         $characterContents = makeUnique($characterContents);
  148.     }
  149.  
  150.     //    Get of the handles and joints
  151.     //
  152.     string $expandedTargets[] = appendArray($targets, $characterContents);
  153.     if (size($characterContents) > 0) {
  154.         $expandedTargets = makeUnique($expandedTargets);
  155.     }
  156.  
  157.     string $handles[] = `ls -type "ikHandle" $expandedTargets`;
  158.     string $joints[] = `ls -type "joint" $expandedTargets`;
  159.  
  160.     int $nOthers = 0;
  161.     string $others[];
  162.  
  163.     string $item;
  164.     for ($item in $expandedTargets) {
  165.         //  First check for non-handles and non-joints that have a
  166.         //  a special .ikBlend attribute (old name was .solverEnable)
  167.         //
  168.         if (size(`ls -type "joint" -type "ikHandle" $item`) == 0 &&
  169.             (size(`ls ($item+".solverEnable")`) ||
  170.              size(`ls ($item+".ikBlend")`)) ) {
  171.             $others[$nOthers++] = $item;
  172.         }
  173.     }
  174.  
  175.     int $nHandles = size($handles);
  176.     int $nJoints = size($joints);
  177.  
  178.     if ($nHandles == 0 && $nJoints == 0 && $nOthers == 0) {
  179.         return $targets;
  180.     }
  181.  
  182.     //    Get the combined list of items to key. Do not worry about duplicates
  183.     //    since the ikFK script is smart enough to handle them.
  184.     //
  185.     string $combined[] = appendArray($handles, $joints);
  186.     $combined = appendArray($combined, $others);
  187.  
  188.     //    There is nothing that IK/FK would be interested in setting.
  189.     //
  190.     if (size($combined) == 0) {
  191.         return $targets;
  192.     } 
  193.  
  194.     catch(ikFK($mode, $combined));
  195.  
  196.     //    Return the unset elements.
  197.     //
  198.     return (removeIntersection($combined, $targets));
  199. }
  200.  
  201. proc string ikFKHandleMembers(string $members, int $mode)
  202. //
  203. //    Description:
  204. //        Sets the IK/FK keys and returns the unset target items.
  205. //        The format is a string bounded by '{' and '}' characters.
  206. //
  207. {
  208.     if (size($members) == 0 || $members == "{}") {
  209.         return $members;
  210.     }
  211.  
  212.     //    Skip the {" and "} sections.
  213.     //
  214.     int $nChars = size($members);
  215.     string $sub = `substring $members 3 ($nChars-2)`;
  216.  
  217.     //    Create an array based on the string and then call the 
  218.     //    ikFKHandleObjects procedure.
  219.     //
  220.     string $buf[];
  221.     tokenize $sub "\", \"" $buf;
  222.  
  223.     string $unused[];
  224.     if (size($buf)) {
  225.         $unused = ikFKHandleObjects($buf, $mode);
  226.     } else {
  227.         return $members;
  228.     }
  229.  
  230.     //    Reconstruct the members string 
  231.     //
  232.     if (size($unused) == 0) {
  233.         return $members;
  234.     } 
  235.  
  236.     int $nUnused = size($unused);
  237.     string $unusedMembers = ("{\"" + $unused[0] + "\"");
  238.     for ($ii = 1; $ii < $nUnused; $ii++) {
  239.         $unusedMembers += (" ,\"" + $unused[$ii] + "\"");
  240.     }
  241.     $unusedMembers += "}";
  242.  
  243.     return $unusedMembers;
  244. }
  245.  
  246. proc string[] ikFKHandleAttributes(string $attrs[], int $mode)
  247. //
  248. //    Description:
  249. //        Sets the ikFK keys for nodes from the list of passed attributes.
  250. //         The unset nodes are returned.
  251. //
  252. {
  253.     int $nIKRelated = 0;
  254.     string $ikRelated[];
  255.  
  256.     int $nCharacters = 0;
  257.     string $characters[];
  258.  
  259.     int $nRemainder = 0;
  260.     string $remainder[];
  261.  
  262.     int $nNodes = 0;
  263.     string $nodes[];
  264.  
  265.     string $item;
  266.     for ($item in $attrs) {
  267.         string $buf[];
  268.         tokenize $item "." $buf;
  269.  
  270.         $nodes[$nNodes++] = $buf[0];
  271.     }
  272.  
  273.     return (ikFKHandleObjects($nodes, $mode));
  274. }
  275.  
  276. proc resetStepTangents(string $stepTangents[])
  277. //
  278. //    Description:
  279. //        Some step tangents may get set back to spline during the general
  280. //        setKeyframe call (after ikFK is called). This resets those tangents
  281. //        back to step.
  282. //
  283. {
  284.     float $time = `currentTime -q`;
  285.  
  286.     string $item;
  287.     for ($item in $stepTangents) {
  288.         if (size(`ls $item`)) {
  289.             catch(`keyTangent -e -t $time -ott step $item`);
  290.         }
  291.     }
  292. }
  293.  
  294. //    Procedure Name:
  295. //        doSetKeyframe
  296. //
  297. //    Description:
  298. //        This is the actual function that calls from the "Set Keyframe" option
  299. //        box.
  300. //
  301. //    Input Arguments:
  302. //    $version: The version of this option box.  Used to know how to 
  303. //    interpret the $args array.
  304. //        "1" : $which, $hierarchy, $channelBox, $control, $shape
  305. //        "2" : $prompt
  306. //        "3" : $breakdown, $selectionConnection
  307. //    
  308. //    $args
  309. //    Version 1
  310. //    [0]        $which .. 1 : set keyframes on all keyable attrs
  311. //                      2 : set keyframes on all manip handle attrs
  312. //                      3 : set keyframes on current manip handle
  313. //                      4 : set keyframes on all manip handle attrs and if no
  314. //                          manip is up set keyframes on all keyable attrs
  315. //            The remaining arguments are only applicable if $which == 1
  316. //    [1]        $hierarchy  0/1 : set keyframe on selected items only, or all below
  317. //    [2]        $channelBox 0/1 : if 1, set keyframes on attrs specified in channel box
  318. //    [3]        $control    0/1 : if 1 and a transform above a shape is selected,
  319. //                                key all control points also
  320. //    [4]        $shape      0/1 : if 1 and a transform above a shape is selected,
  321. //                                key attributes of shape as well
  322. //                                (excluding control pts)
  323. //    Version 2
  324. //    [5]        $prompt     : 1 prompt user for list of times at which to set keys
  325. //                          {0} do not prompt user; i.e., set keys at current time
  326. //    Version 3
  327. //    [6]        $breakdown    : 1 set breakdowns
  328. //                          {0} set keys
  329. //    [7]        $selectionConnection    name of selection connection to use
  330. //    
  331. //    Version 4
  332. //    [8]        $useIKFK    : If 1, use IK/FK on selected joints and ikHandles.
  333. //
  334. //    Return Value:
  335. //        number of attributes keyframed
  336. //
  337.  
  338. global proc int doSetKeyframeArgList( string $version, string $args[] )
  339. {
  340.     int        $versionNum                = $version;
  341.  
  342.     int        $which                    = $args[0];
  343.     int        $hierarchy                = ($which == 4 ? 0 : $args[1]);
  344.     int        $channelBox                = ($which == 4 ? 0 : $args[2]);
  345.     int        $control                = ($which == 4 ? 0 : $args[3]);
  346.     int        $shape                    = ($which == 4 ? 0 : $args[4]);
  347.     int        $prompt                    = ($versionNum >= 2 ? $args[5] : 0);
  348.     int        $breakdown                = ($versionNum >= 3 ? $args[6] : 0);
  349.     string    $selectionConnection    = ($versionNum >= 3 ? $args[7] : "");
  350.     int     $useIKFK                = ($versionNum >= 4 ? $args[8] : 0);
  351.  
  352.     string    $attrsToKey[];
  353.     int        $i;
  354.     int        $count;
  355.     int        $total = 0;
  356.  
  357.     int     $ikFKMode = 1;    //    Defines the behavior of neighboring keys.
  358.                             //    See the ikFK.mel script for details.
  359.  
  360.     global     string    $gSetIKFKStepTangentList[];
  361.     clear($gSetIKFKStepTangentList);
  362.  
  363.     //    If $prompt is on, ignore $useIKFK
  364.     //
  365.     if ($prompt && $useIKFK) {
  366.         $useIKFK = 0;
  367.     }
  368.  
  369.     string $cmd = "setKeyframe -breakdown " + $breakdown + " ";
  370.     string $ikFKCmd = "";
  371.  
  372.     if( $prompt ) {
  373.         string $response = `promptDialog
  374.             -title ($breakdown ? "Set Breakdown" : "Set Key")
  375.             -message "Enter list of times:"
  376.             -text ""
  377.             -button "OK"
  378.             -button "Cancel"
  379.             -defaultButton "OK"
  380.             -cancelButton "Cancel"
  381.             -dismissString "Cancel"`;
  382.  
  383.         // Give the user a chance to cancel
  384.         //
  385.         if( $response != "OK" ) {
  386.             return 0;
  387.         }
  388.  
  389.         string $keyTimes = `promptDialog -query -text`;
  390.         string $buffer[];
  391.  
  392.         // $keyTimes would be easier to work with as an array of
  393.         // elements.  Calling this proc separates out the elements
  394.         // based on whitespace or commas.
  395.         //
  396.         if( tokenizeList( $keyTimes, $buffer ) ) {
  397.             // Add each of the times listed to the command, preceded by 
  398.             // the -t flag.
  399.             //
  400.             int $timeAdded = 0;
  401.  
  402.             $keyTimes = "";
  403.             for( $time in $buffer ) {
  404.                 if( size( $time ) > 0 ) {
  405.                     $keyTimes = ( $keyTimes + "-t " + $time + " " );
  406.                     $timeAdded = 1;
  407.                 }
  408.             }
  409.             
  410.             // If the user entered a bunch of spaces,
  411.             // there are no times, but $buffer isn't technically
  412.             // empty.  Just return, and don't set any keys.
  413.             //
  414.             if( !$timeAdded ) {
  415.                 return 0;
  416.             }
  417.             
  418.             $cmd = ( $cmd + $keyTimes );
  419.         } else {
  420.             // Don't spit out a silly error if there's no list.
  421.             //
  422.             if( $keyTimes != "" ) {
  423.                 error( "Invalid list of times" );
  424.             }
  425.             return 0;
  426.         }
  427.     }
  428.  
  429.     // Get the target objects
  430.     //
  431.     string $members = expandSelectionConnection ($selectionConnection);
  432.     int $hasObjects = false;
  433.  
  434.     if ($which == 4)
  435.     {
  436.         $attrsToKey = `listAnimatable -manip`;
  437.         int $nAttrs = size($attrsToKey);
  438.  
  439.         if ($useIKFK && $nAttrs > 0) {
  440.             ikFKHandleAttributes($attrsToKey, $ikFKMode);
  441.         }
  442.  
  443.         for ($i = 0; $i < $nAttrs; $i++)
  444.         {
  445.             $count = evalEcho( $cmd + $attrsToKey[$i] );
  446.             $total = $total + $count;
  447.         }
  448.     }
  449.  
  450.     if (($which == 1) || ($which == 4))
  451.     {
  452.         if ($hierarchy == 1) {
  453.             $cmd = $cmd + "-hierarchy below ";
  454.         } else {
  455.             $cmd = $cmd + "-hierarchy none ";
  456.         }
  457.  
  458.         if ($channelBox == 1) {
  459.             if ($useIKFK) {
  460.                 //    Make sure that the IK/FK code is executed.
  461.                 //    The generic setKeyframe code will set keys on this
  462.                 //    twice, but that should not be a problem.
  463.                 //
  464.                 string $objects[] = selectedChannelBoxObjects();
  465.                 ikFKHandleObjects($objects, $ikFKMode);
  466.             }
  467.  
  468.             string $syntax[] = keySetOptionBoxCommon( { "setKeyframe", 
  469.                                                         "unknown", 
  470.                                                         "channelBoxSyntax" } );
  471.             if( size( $syntax[0] ) == 0 ) {
  472.                 warning("No channels selected in channel box");
  473.                 return 0;
  474.             }
  475.         
  476.             $cmd = $cmd + $syntax[0];
  477.  
  478.             // and finally execute the command
  479.             //
  480.             $total = $total + evalEcho($cmd);
  481.             $hasObjects = true;
  482.         }
  483.         else if( $members != "" ) {
  484.             if ($useIKFK) {
  485.                 //    process the members string.
  486.                 //
  487.                 ikFKHandleMembers($members, $ikFKMode);
  488.             }
  489.  
  490.             // Only add the selection connection to the cmd if
  491.             // there are NO active keys.
  492.             //
  493.             if ($members == "{}") {
  494.                 $cmd = "";
  495.                 warning (("No objects selected to set " + 
  496.                           ($breakdown ? "breakdowns" : "keys")));
  497.             }
  498.             else {
  499.                 $cmd = ($cmd + 
  500.                     "-controlPoints " + $control + " " +
  501.                     "-shape " + $shape + " " +
  502.                     $members
  503.                  );
  504.                 $total = $total + evalEcho ($cmd);
  505.                 $hasObjects = true;
  506.             }
  507.         }
  508.         else
  509.         {
  510.             string $objects[] = `ls -sl`;
  511.             if ($useIKFK) {
  512.                 ikFKHandleObjects($objects, $ikFKMode);
  513.             }
  514.  
  515.             $hasObjects = (size ($objects) > 0 ? true : false);
  516.             $cmd = $cmd +
  517.                    ("-controlPoints " + $control +
  518.                     " -shape " + $shape);
  519.             if (!$hasObjects && ($useIKFK && $total == 0)) {
  520.                 warning (("No objects selected to set " + 
  521.                           ($breakdown ? "breakdowns" : "keys")));
  522.             }
  523.             else {
  524.                 if ($hasObjects) {
  525.                     $total = evalEcho($cmd);
  526.                 }
  527.             }
  528.         }
  529.     }
  530.     else if (($which == 2) || ($which == 3))
  531.     {
  532.         if ($which == 2)
  533.             $attrsToKey = `listAnimatable -manip`;
  534.         else    // $which == 3
  535.             $attrsToKey = `listAnimatable -manipHandle`;
  536.  
  537.         int $nItems = size($attrsToKey);
  538.         if ($useIKFK) {
  539.             ikFKHandleAttributes($attrsToKey, $ikFKMode);
  540.         }
  541.  
  542.         for ($i = 0; $i < size($attrsToKey); $i++)
  543.         {
  544.             $count = evalEcho( $cmd + $attrsToKey[$i] );
  545.             $total = $total + $count;
  546.         }
  547.     }
  548.  
  549.     if (($total == 0) && $hasObjects)
  550.     {
  551.         switch($which)
  552.         {
  553.             case 1:    // all keyable
  554.                 warning("Active objects have no keyable attributes");
  555.                 break;
  556.             case 2: // all manip handles
  557.                 warning("Current manipulator has no keyable attributes");
  558.                 break;
  559.             case 3: // current manip handle
  560.                 warning("Current manipulator handle has no keyable attributes");
  561.                 break;
  562.             case 4: // all manip handles or all keyable
  563.                 warning("Current manipulator and active objects have no keyable attributes");
  564.                 break;
  565.         }
  566.     }
  567.  
  568.     if (size($gSetIKFKStepTangentList)) {
  569.         resetStepTangents($gSetIKFKStepTangentList);
  570.         clear($gSetIKFKStepTangentList);
  571.     }
  572.  
  573.     return $total;
  574. }
  575.